/*
 * Copyright 2010-2012 Susanta Tewari. <freecode4susant@users.sourceforge.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package genomemap.provider;

import commons.provider.Provider;
import commons.provider.ProviderException;
import commons.provider.Providers.FileBasedProvider;
import genomemap.data.AssignmentData;
import genomemap.data.KSA00Data;
import genomemap.data.OrganismData;
import genomemap.data.TAB08Data;
import genomemap.map.GeneticMapFunction;
import genomemap.model.KSA00;
import genomemap.model.TAB08;

import java.io.File;
import java.util.Set;

/**
 * @author Susanta Tewari
 * @history First created on Mar 19, 2012
 */
@SuppressWarnings("MarkerInterface")
public interface Providers {

    /**
     * description
     *
     * @version 1.3.0 12/10/09
     * @author Susanta Tewari
     * @since 1.3.0
     */
    public interface AssignmentDataProviderFileBased extends FileBasedProvider<AssignmentData> {}

    /**
     * @version 1.3.0
     * @since 1.3.0
     * @history Created on 03/17/2013
     * @author Susanta Tewari
     */
    public interface GeneticMapFunctionProvider extends Provider<GeneticMapFunction> {}

    /**
     * description
     *
     * @version 1.3.0 12/10/09
     * @author Susanta Tewari
     * @since 1.3.0
     */
    public interface KSA00DataProviderFileBased
            extends commons.provider.Providers.ModelDataProviderFileBased<KSA00, KSA00Data> {}

    /**
     * DataSimulatorProvider for data KSA00Data.
     *
     * @version 1.3.0 12/10/09
     * @author Susanta Tewari
     * @since 1.3.0
     */
    public interface KSA00DataSimulatorProvider
            extends commons.provider.Providers.DataSimulatorProvider<KSA00, KSA00Data> {}

    /**
     * description
     *
     * @version 1.3.0 12/10/09
     * @author Susanta Tewari
     * @since 1.3.0
     */
    public interface KSA00EstimatorProvider
            extends commons.provider.Providers.ModelEstimatorProvider<KSA00, KSA00Data> {}

    /**
     * ModelGeneratorProvider for model KSA00.
     *
     * @version 1.3.0 12/10/09
     * @author Susanta Tewari
     * @since 1.3.0
     */
    public interface KSA00GeneratorProvider
            extends commons.provider.Providers.ModelGeneratorProvider<KSA00, KSA00> {}

    /**
     * description
     *
     * @version 1.3.0 12/10/09
     * @author Susanta Tewari
     * @since 1.3.0
     */
    public interface KSA00LHoodProvider
            extends commons.provider.Providers.LikelihoodComputerProvider<KSA00, KSA00Data> {}

    /**
     * This protocol of this provider: <ol> <li> {@link #setDataDirectory(java.io.File)
     * setDataDirectory}</li> <li> {@link #getAvailableLinkageGroups()
     * getAvailableLinkageGroups}</li> <li> {@link #setLinkageGroups(java.util.Set)
     * setLinkageGroups}</li> <li> {@link #create() create}</li> </ol>
     *
     * @author Susanta Tewari
     * @version 1.0 Jul 8, 2011
     */
    public interface OrganismDataProvider extends Provider<OrganismData> {

        /**
         * The provider checks if the directory follows the specification below. After this method
         * returns, the caller should invoke {@link #getAvailableLinkageGroups()
         * getAvailableLinkageGroups} to get the available linkage groups. A subset (separate
         * instance) of that groups can be provided in {@link #setLinkageGroups(java.util.Set)
         * setLinkageGroups}, followed by {@link #create() create} to get an instance. <p>The
         * directory contents specification: <ul> <li><b><a href="doc-files/genotypes.xml.txt">genotypes.xml</a></b>:
         * contains genes and their genotypes on a number of offsprings for all the linkage groups
         * under study. The same offsprings are used for all the linkage groups. Genotype contains
         * missing values. A deterministic (i.e. reproducible) missing value algorithm is used for
         * imputation.</li> <li><b><a href="doc-files/ch_1.cosmid-sample.txt">ch_[LINKAGE-GROUP].cosmid</a></b>:
         * contains hybridization data for clones and probes. Clone names are included but probe
         * names are given in a separate file. Some of these probes are not suitable for analysis as
         * they violate model conditions, e.g., non-overlapping, self-hybridizing, unique etc. An
         * algorithm is used to prune these probes to select a subset of probes suitable for
         * analysis. These are big files, size being about 1 MB. Linkage groups 5 and 1 are the
         * biggest and linkage group 7 being the smallest.</li> <li><b><a
         * href="doc-files/probe_names.xml.txt">probe_names.xml</a></b>: contains probe names for
         * probes in ch_[LINKAGE-GROUP].cosmid</li>. Their order corresponds to the order in
         * ch_[LINKAGE-GROUP].cosmid file. <li><b><a href="doc-files/assignment.xml.txt">assignment.xml</a></b>:
         * It contains gene-clone assignment information for genes in genotypes.xml and clones in
         * the corresponding ch_[LINKAGE-GROUP].cosmid file. The assignment information is used to
         * update physical maps with information from genetic maps and <i>vice versa</i>. <p>This is
         * a curated file. It was created from a gene-clone complementation data obtained from Dr.
         * Arnold and online data available at http://www.broadinstitute.org/annotation/genome/neurospora/FeatureSearch.html.
         *
         * @param dataDir the data directory containing the files specified above
         * @throws ProviderException if <ol> <li>{@code dataDir} is not a directory</li> <li>the
         * contents of the directory does not follow the above specification</li> </ol>
         */
        void setDataDirectory(File dataDir) throws ProviderException;

        /**
         * The data is organized by the linkage groups spread across multiple files. It calculates
         * the linkage groups supported by the data. <p> This method should be called only after a
         * successfull call to {@link #setDataDirectory(java.io.File) setDataDirectory}.
         *
         * @return the set (unmodifiable) of linkage groups supported by the data
         * @throws ProviderException if <ol> <li>{@link #setDataDirectory(java.io.File)
         * setDataDirectory} was not called before sucessfully</li> <li>any other error occurred
         * while finding the available linkage groups</li> </ol>
         */
        Set<Integer> getAvailableLinkageGroups() throws ProviderException;

        /**
         * Specifies the linkage groups for which the data should be created.
         *
         * @param linkageGroups a subset of the supported linkage groups obtained via {@link
         * #setDataDirectory(java.io.File) setDataDirectory}.
         * @throws ProviderException if <ol> <li>{@code linkageGroups} is not a subset of {@link
         * #setDataDirectory(java.io.File) setDataDirectory}</li> </ol>
         */
        void setLinkageGroups(Set<Integer> linkageGroups) throws ProviderException;
    }

    /**
     * description
     *
     * @version 1.3.0 12/10/09
     * @author Susanta Tewari
     * @since 1.3.0
     */
    public interface TAB08DataProviderFileBased
            extends commons.provider.Providers.ModelDataProviderFileBased<TAB08, TAB08Data> {}

    /**
     * DataSimulatorProvider for data TAB08Data.
     *
     * @version 1.3.0 12/10/09
     * @author Susanta Tewari
     * @since 1.3.0
     */
    public interface TAB08DataSimulatorProvider
            extends commons.provider.Providers.DataSimulatorProvider<TAB08, TAB08Data> {}

    /**
     * description
     *
     * @version 1.3.0 12/10/09
     * @author Susanta Tewari
     * @since 1.3.0
     */
    public interface TAB08EstimatorProvider
            extends commons.provider.Providers.ModelEstimatorProvider<TAB08, TAB08Data> {}

    /**
     * ModelGeneratorProvider for model TAB08.
     *
     * @version 1.3.0 12/10/09
     * @author Susanta Tewari
     * @since 1.3.0
     */
    public interface TAB08GeneratorProvider
            extends commons.provider.Providers.ModelGeneratorProvider<TAB08, TAB08> {}

    /**
     * Interface description
     *
     * @version 1.3.0 12/10/09
     * @author Susanta Tewari
     * @since 1.3.0
     */
    public interface TAB08LHoodProvider
            extends commons.provider.Providers.LikelihoodComputerProvider<TAB08, TAB08Data> {}
}
